package com.alan.shiro.controller;

import com.alan.shiro.bean.ResultMap;
import com.alan.shiro.bean.Role;
import com.alan.shiro.bean.User;
import com.alan.shiro.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Auther: Alan liu
 * @Date: 2018/12/11 19:18
 * @Description: LoginController
 */
@Controller
@Slf4j
public class LoginController {

    @Autowired
    private UserService userService;

    /**
     * 跳转到无权限页面
     * @return
     */
    @RequestMapping(value = "/notRole", method = RequestMethod.GET)
    public String notRole() {

        return "/html/notRoleAlan";
    }



    /**
     * 主页面，mapping中了""，因用filter实现登入时，登入成功后会返回到""该地址上。
     * @param model
     * @param response
     * @return
     */
    @RequestMapping(value = {"/loginSuccess",""}, method = RequestMethod.GET)
    public String loginSuccess(Model model, HttpServletResponse response){
        Subject subject = SecurityUtils.getSubject();
        //根据权限，指定返回数据
        String username = (String)subject.getPrincipal();
        User user = userService.findByName(username);
        Role role = user.getRoles().get(0);
        String msg = "";
        if ("user".equals(role.getRoleName())) {
            msg = "欢迎登陆:"+username;
        }
        if ("admin".equals(role.getRoleName())) {
            msg = "欢迎来到管理员页面:"+username;
        }
        model.addAttribute("msg",msg);
        return "/html/loginSuccess";
    }

    /**
     * FormAuthenticationFilter 实现登录：
     *    进入该方法前会先进入FormAuthenticationFilter类中。
     *    如登登录成功会 redirect 到shiro配置时的successUrl中
     *    如登录失败后会进入该方法，然后通过request.getAttribute("shiroLoginFailure")
     *    得到异常原因，进行判定。
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value = "/login")
    public String login(Model model, HttpServletRequest request) {
        System.out.println("LoginController.login()");
        // 登录失败从request中获取shiro处理的异常信息。
        // shiroLoginFailure:就是shiro异常类的全类名.
        String exception = (String) request.getAttribute("shiroLoginFailure");
        System.out.println("exception=" + exception);
        String msg = "";
        if (exception != null) {
            if (UnknownAccountException.class.getName().equals(exception)) {
                System.out.println("UnknownAccountException -- > 账号不存在：");
                msg = "UnknownAccountException -- > 账号不存在：";
            } else if (IncorrectCredentialsException.class.getName().equals(exception)) {
                System.out.println("IncorrectCredentialsException -- > 密码不正确：");
                msg = "IncorrectCredentialsException -- > 密码不正确：";
            } else if ("kaptchaValidateFailed".equals(exception)) {
                System.out.println("kaptchaValidateFailed -- > 验证码错误");
                msg = "kaptchaValidateFailed -- > 验证码错误";
            } else {
                msg = "else >> "+exception;
                System.out.println("else -- >" + exception);
            }
        }
        model.addAttribute("msg",msg);
        // 此方法不处理登录成功,由shiro进行处理
        return "/html/login";
    }

    /**
     * 登陆
     *      手动调用subject.login(token)实现登录
     * @param msg 错误信息
     */
    @RequestMapping(value = "/loginAlan")
    public String loginAlan(Model model,String msg,HttpServletRequest request) {
        // 从SecurityUtils里边创建一个 subject
        Subject subject = SecurityUtils.getSubject();
        //检查是否登录
        if(subject.isAuthenticated()){
            return "redirect:/loginSuccessAlan";
        }
        model.addAttribute("msg",msg);
        return "/html/loginAlan";
    }

    /**
     * 手动调用subject.login(token);实现登入，
     * 页面跳转由代码控制
     * @param username
     * @param password
     * @param request
     * @return
     */
    @RequestMapping(value = "/loginForm",method = RequestMethod.POST)
    public String loginForm(String username, String password, HttpServletRequest request) {
        // 从SecurityUtils里边创建一个 subject
        Subject subject = SecurityUtils.getSubject();
        //检查是否登录
        if(subject.isAuthenticated()){
            return "redirect:/loginSuccessAlan";
        }
        // 在认证提交前准备 token（令牌）
//        String passwordT = password
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        // 执行认证登陆
        try {
            subject.login(token);
        }catch (IncorrectCredentialsException e){
            //交给shiro配对密码时，如密码不配对会抛改异常
            log.info("密码不对！:{}",e);
            String msg = e.getMessage();
            return "redirect:/loginAlan?msg="+msg;
        }
        return "redirect:/loginSuccessAlan";
    }

    /**
     * 跳转到登出页面
     * @return
     */
    @RequestMapping(value = "/logoutAlan", method = RequestMethod.GET)
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        //注销
        subject.logout();
        return "/html/logoutAlan";
    }

    @RequestMapping(value = {"/loginSuccessAlan"}, method = RequestMethod.GET)
    public String loginSuccessAlan(Model model, HttpServletResponse response){
        model.addAttribute("msg","hello");
        return "/html/loginSuccessAlan";
    }

}
